﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetTopologySuite_Silverlight.IO
{
    public class Utf8Converter
    {
        private UTF8Encoding _encoding = new UTF8Encoding();

        /// <summary>
        /// A charset table that contains {utf8 code, target code} values.
        /// </summary>
        public Dictionary<int ,int> CharsetTable { get; set; }

        /// <summary>
        /// Single byte limit.
        /// </summary>
        public int SingleByteMax { get; set; }

        public Utf8Converter()
        {
            SetAsciiDictionary();
            SingleByteMax = 256;
        }

        public byte[] GetEncodedStringBytes(string utf8String, int length)
        {
            byte[] bytes = utf8String.SelectMany(GetEncodedCharBytes).ToArray();
            if ( bytes.Length <= length)
            {
                return bytes;
            }

            return CutStringBytes(bytes, length).ToArray();
        }

        IEnumerable<byte> CutStringBytes(byte[] bytes, int length )
        {
            for (int i = 0; i < length; i++ )
            {
                yield return bytes[i];
            }
        }

        public byte[] GetEncodedStringBytes(string utf8String)
        {
            return utf8String.SelectMany(GetEncodedCharBytes).ToArray();
        }

        public byte[] GetEncodedCharBytes(char utf8Char)
        {
            int encodedNum;
            try
            {
                encodedNum = CharsetTable[utf8Char];
            } catch(Exception)
            {
                // if the charset table doesn't have any code, set a space.
                encodedNum = 0x20;
            }

            byte[] encodedByte = BitConverter.GetBytes(encodedNum);
            if ( encodedNum <= SingleByteMax)
            {
                // single byte
                return new byte[1]{encodedByte[0]};
            } 
            // double byte
            return new byte[2]{encodedByte[1], encodedByte[0]};
        }


        /// <summary>
        /// Set default charset dictionary(ascii);
        /// </summary>
        void SetAsciiDictionary()
        {
            CharsetTable = new Dictionary<int, int>()
                               {
                                   {0x0000, 0x00},
                                   {0x0001, 0x01},
                                   {0x0002, 0x02},
                                   {0x0003, 0x03},
                                   {0x0004, 0x04},
                                   {0x0005, 0x05},
                                   {0x0006, 0x06},
                                   {0x0007, 0x07},
                                   {0x0008, 0x08},
                                   {0x0009, 0x09},
                                   {0x000A, 0x0A},
                                   {0x000B, 0x0B},
                                   {0x000C, 0x0C},
                                   {0x000D, 0x0D},
                                   {0x000E, 0x0E},
                                   {0x000F, 0x0F},
                                   {0x0010, 0x10},
                                   {0x0011, 0x11},
                                   {0x0012, 0x12},
                                   {0x0013, 0x13},
                                   {0x0014, 0x14},
                                   {0x0015, 0x15},
                                   {0x0016, 0x16},
                                   {0x0017, 0x17},
                                   {0x0018, 0x18},
                                   {0x0019, 0x19},
                                   {0x001A, 0x1A},
                                   {0x001B, 0x1B},
                                   {0x001C, 0x1C},
                                   {0x001D, 0x1D},
                                   {0x001E, 0x1E},
                                   {0x001F, 0x1F},
                                   {0x0020, 0x20},
                                   {0x0021, 0x21},
                                   {0x0022, 0x22},
                                   {0x0023, 0x23},
                                   {0x0024, 0x24},
                                   {0x0025, 0x25},
                                   {0x0026, 0x26},
                                   {0x0027, 0x27},
                                   {0x0028, 0x28},
                                   {0x0029, 0x29},
                                   {0x002A, 0x2A},
                                   {0x002B, 0x2B},
                                   {0x002C, 0x2C},
                                   {0x002D, 0x2D},
                                   {0x002E, 0x2E},
                                   {0x002F, 0x2F},
                                   {0x0030, 0x30},
                                   {0x0031, 0x31},
                                   {0x0032, 0x32},
                                   {0x0033, 0x33},
                                   {0x0034, 0x34},
                                   {0x0035, 0x35},
                                   {0x0036, 0x36},
                                   {0x0037, 0x37},
                                   {0x0038, 0x38},
                                   {0x0039, 0x39},
                                   {0x003A, 0x3A},
                                   {0x003B, 0x3B},
                                   {0x003C, 0x3C},
                                   {0x003D, 0x3D},
                                   {0x003E, 0x3E},
                                   {0x003F, 0x3F},
                                   {0x0040, 0x40},
                                   {0x0041, 0x41},
                                   {0x0042, 0x42},
                                   {0x0043, 0x43},
                                   {0x0044, 0x44},
                                   {0x0045, 0x45},
                                   {0x0046, 0x46},
                                   {0x0047, 0x47},
                                   {0x0048, 0x48},
                                   {0x0049, 0x49},
                                   {0x004A, 0x4A},
                                   {0x004B, 0x4B},
                                   {0x004C, 0x4C},
                                   {0x004D, 0x4D},
                                   {0x004E, 0x4E},
                                   {0x004F, 0x4F},
                                   {0x0050, 0x50},
                                   {0x0051, 0x51},
                                   {0x0052, 0x52},
                                   {0x0053, 0x53},
                                   {0x0054, 0x54},
                                   {0x0055, 0x55},
                                   {0x0056, 0x56},
                                   {0x0057, 0x57},
                                   {0x0058, 0x58},
                                   {0x0059, 0x59},
                                   {0x005A, 0x5A},
                                   {0x005B, 0x5B},
                                   {0x005C, 0x5C},
                                   {0x005D, 0x5D},
                                   {0x005E, 0x5E},
                                   {0x005F, 0x5F},
                                   {0x0060, 0x60},
                                   {0x0061, 0x61},
                                   {0x0062, 0x62},
                                   {0x0063, 0x63},
                                   {0x0064, 0x64},
                                   {0x0065, 0x65},
                                   {0x0066, 0x66},
                                   {0x0067, 0x67},
                                   {0x0068, 0x68},
                                   {0x0069, 0x69},
                                   {0x006A, 0x6A},
                                   {0x006B, 0x6B},
                                   {0x006C, 0x6C},
                                   {0x006D, 0x6D},
                                   {0x006E, 0x6E},
                                   {0x006F, 0x6F},
                                   {0x0070, 0x70},
                                   {0x0071, 0x71},
                                   {0x0072, 0x72},
                                   {0x0073, 0x73},
                                   {0x0074, 0x74},
                                   {0x0075, 0x75},
                                   {0x0076, 0x76},
                                   {0x0077, 0x77},
                                   {0x0078, 0x78},
                                   {0x0079, 0x79},
                                   {0x007A, 0x7A},
                                   {0x007B, 0x7B},
                                   {0x007C, 0x7C},
                                   {0x007D, 0x7D},
                                   {0x007E, 0x7E},
                                   {0x007F, 0x7F},
                               };
        }
    }

}